package cn.turboinfo.fuyang.api.provider.admin.component.session;

import cn.turboinfo.fuyang.api.entity.admin.constant.AdminRequestConstants;
import cn.turboinfo.fuyang.api.provider.admin.framework.shiro.session.AdminSession;
import cn.turboinfo.fuyang.api.provider.admin.framework.shiro.session.AdminSessionFactory;
import lombok.RequiredArgsConstructor;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.Session;

import java.util.Map;

@RequiredArgsConstructor
public class AdminSessionHelper {

    protected final AdminSessionFactory adminSessionFactory;

    protected final FindByIndexNameSessionRepository<? extends Session> findByIndexNameSessionRepository;

    @Value("${kit.admin.login.session.timeout:300000}")
    private long sessionTimeout;

    public AdminSession getSession() {
        Subject subject = SecurityUtils.getSubject();
        return (AdminSession) subject.getSession().getAttribute(AdminRequestConstants.AttrSession);
    }

    public Long getSessionSysUserId() {
        return getSession().getSysUserId();
    }

    public void initSession() {
        Subject subject = SecurityUtils.getSubject();
        Long sysUserId = (Long) subject.getPrincipal();
        // 用于 Spring Session 从 Redis 中按 sysUserId 查找在线用户
        subject.getSession().setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, sysUserId.toString());
        subject.getSession().setAttribute(AdminRequestConstants.AttrSession, adminSessionFactory.createAdminSession(sysUserId));
        subject.getSession().setTimeout(sessionTimeout);
    }

    public void refreshSession() {
        Subject subject = SecurityUtils.getSubject();
        AdminSession adminSession = getSession();
        adminSessionFactory.refreshAdminSessionBySysUser(adminSession, adminSession.getSysUserId());
        subject.getSession().setAttribute(AdminRequestConstants.AttrSession, adminSession);
        subject.getSession().setTimeout(sessionTimeout);
    }

    //遍历同一个账户的session (Spring Session 封装的对象)
    @SuppressWarnings("unchecked")
    public Map<String, Session> findSessionMap(Long sysUserId) {
        return (Map<String, Session>) findByIndexNameSessionRepository.findByPrincipalName(sysUserId.toString());
    }

    public void deleteSessionById(String sessionId) {
        findByIndexNameSessionRepository.deleteById(sessionId);
    }
}
